﻿using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Options;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MqttRedis
{
    public partial class Mqtt : Form
    {
        private IMqttClient Client { get; set; }
        public Mqtt()
        {
            InitializeComponent();

            tbMqttIP.Text = "39.105.189.49";
            tbMqttPort.Text = "1883";
            tbMqttAccount.Text = "admin";
            tbMqttPassword.Text = "password";
            TBMqttSubscribe.Text = "deviceHeartbeat";

            string[] topics = { "11", "22" };

            cbMqttTopic.AutoCompleteSource = AutoCompleteSource.CustomSource;
            cbMqttTopic.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
            cbMqttTopic.AutoCompleteCustomSource.AddRange(topics);
        }

        private void btnMqttConnect_Click(object sender, EventArgs e)
        {
            string ip = tbMqttIP.Text;
            int port = Convert.ToInt32(tbMqttPort.Text);
            string account = tbMqttAccount.Text;
            string password = tbMqttPassword.Text;

            string clientId = Guid.NewGuid().ToString();

            var options = new MqttClientOptionsBuilder()
                .WithTcpServer(ip, port)
                .WithClientId(clientId)
                .WithCredentials(account, password)
                .Build();

            Client = new MqttFactory().CreateMqttClient();

            Client.UseConnectedHandler(c =>
            {
                //MqttTopicFilter filter1 = new MqttTopicFilterBuilder().WithTopic("WuZhen/ToiletDisplayToilets/B016DC25-B788-4794-9115-3ECFCCD3021D").Build();
                //MqttTopicFilter filter1 = new MqttTopicFilterBuilder().WithTopic("WuZhen/ToiletDisplayPits/B016DC25-B788-4794-9115-3ECFCCD3021D").Build();
                MqttTopicFilter filter1 = new MqttTopicFilterBuilder().WithTopic("public/Device").Build();//public/ToiletDevice
                //Client.SubscribeAsync(filter1, filter2,filter3);
                Client.SubscribeAsync(filter1);

                //MessageBox.Show("连接成功");

            }).UseDisconnectedHandler(c =>
            {
                MessageBox.Show("断开成功");
            })
            .UseApplicationMessageReceivedHandler(c =>
            {
                ////string info = $"当前时间：{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}\r\n";

                string str = Encoding.UTF8.GetString(c.ApplicationMessage.Payload);

                //////List<PitRealTime> pits = JsonSerializer.Deserialize<List<PitRealTime>>(str);

                //////pits = pits.Where(p => p.ToiletId == "B016DC25-B788-4794-9115-3ECFCCD3021D").OrderBy(p => p.PitType).ThenBy(p => p.PitCode).ToList();
                //////foreach (PitRealTime item in pits)
                //////{
                //////    info += $"编号：{item.PitCode}，坑位类型：{item.PitType}，状态：{item.PitStatus}\r\n";
                //////}
                ////tbMqttMessage.BeginInvoke(new Action(() =>
                ////{
                ////    tbMqttMessage.Text = str;
                ////}));
                ///
                if (c.ApplicationMessage.Topic == TBMqttSubscribe.Text)
                {
                    //str = DateTimeOffset.FromUnixTimeMilliseconds(Convert.ToInt64(str)).AddHours(8).ToString("yyyy-MM-dd HH:mm:ss.fff");

                    if (str.Contains(":104,") && str.Contains(TBContains.Text))
                    {
                        tbMqttMessage.BeginInvoke(new Action(() =>
                        {
                            tbMqttMessage.AppendText(str + "\r\n");
                        }));
                    }
                }
            });

            Client.ConnectAsync(options);
        }

        private void btnMqttDisConnect_Click(object sender, EventArgs e)
        {
            Client.DisconnectAsync();
        }

        public void Publish(string data, string topic)
        {
            var msg = new MqttApplicationMessageBuilder()
                .WithTopic(topic)
                .WithPayload(data)
                .WithExactlyOnceQoS().
                WithRetainFlag().Build();
            if (Client.IsConnected)
            {
                Client.PublishAsync(msg);
            }
            else
            {
                Console.WriteLine("发送时没有连接");
            }
        }

        private void btnMqttSend_Click(object sender, EventArgs e)
        {
            string content = tbMqttSend.Text;
            string topic = "public/ToiletDevice";//cbMqttTopic.Text;
            Publish(content, topic);
        }

        private void OpenRedis_Click(object sender, EventArgs e)
        {
            Redis redis = new();
            redis.ShowDialog();
        }

        private void BTMqttSubscribe_Click(object sender, EventArgs e)
        {
            string topic = TBMqttSubscribe.Text;
            MqttTopicFilter filter = new MqttTopicFilterBuilder().WithTopic(topic).Build();
            Client.SubscribeAsync(filter);
            MessageBox.Show("订阅成功");
        }
    }

    public class PitRealTime
    {
        public string PitCode { get; set; }
        public string ToiletId { get; set; }

        /// <summary>
        /// 坑位状态
        /// -1异常 0正常 1占用 2入厕过长 3一键告警
        /// </summary>
        public int PitStatus { get; set; }
        public int PitType { get; set; }
    }
}
